package com.niodata.dp.mybatis;

import com.niodata.dp.collection.WrappedList;
import com.niodata.dp.util.JsonUtil;
import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.apache.ibatis.type.JdbcType;

/**
 * common wrapped list type handler,store data as json.
 * json content struct:
 * fistLine: entity full class name
 * second line: json
 *
 */
public class DefaultWrappedListTypeHandler extends AbstractWrappedListTypeHandler<WrappedList> {

  /**
   * not use it.
   * @return class
   */
  public Class getEntityType() {
    return Object.class;
  }

  @Override
  public JdbcType getJdbcType() {
    return JdbcType.LONGVARCHAR;
  }

  @Override
  public Class getTypeHandlerClass() {
    return DefaultWrappedListTypeHandler.class;
  }

  @Override
  public Class getJavaClass() {
    return WrappedList.class;
  }

  @Override
  public void setNonNullParameter(
        PreparedStatement ps, int i, WrappedList parameter, JdbcType jdbcType) throws SQLException {
    try {

      String json = JsonUtil.toJson(parameter);
      String className = "";
      if (parameter.getList() != null && parameter.getList().size() > 0) {
        className = parameter.getList().get(0).getClass().getCanonicalName();
      }
      json = className + "\n" + json;
      ps.setString(i, json);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Override
  public WrappedList getNullableResult(ResultSet rs, String columnName) throws SQLException {
    String json = rs.getString(columnName);
    if (json == null || json.length() == 0) {
      return null;
    }
    int end = json.indexOf("\n");
    String className = json.substring(0, end).trim();
    if (className.equals("")) {
      return WrappedList.emptyList();
    }
    json = json.substring(end + 1).trim();
    try {
      Class entityClass = Class.forName(className);
      List list = JsonUtil.fromJsonList(entityClass, json);
      return new WrappedList(list);
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }

  @Override
  public WrappedList getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    String json = rs.getString(columnIndex);
    if (json == null || json.length() == 0) {
      return null;
    }
    int end = json.indexOf("\n");
    String className = json.substring(0, end).trim();
    if (className.equals("")) {
      return WrappedList.emptyList();
    }
    json = json.substring(end + 1).trim();
    try {
      Class entityClass = Class.forName(className);
      List list = JsonUtil.fromJsonList(entityClass, json);
      return new WrappedList(list);
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }

  @Override
  public WrappedList getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    return null;
  }
}
